import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: val
 * Date: 9/5/13
 * Time: 9:57 PM
 * To change this template use File | Settings | File Templates.
 */
public class Altimeter  extends Application {
    private Stage stage;
    private Group root;
    private VBox vBox;
    private HBox hBox;
    private ArrayList<Path> distanceLines = new ArrayList<Path>();
    private ArrayList<Path> angleLines = new ArrayList<Path>();
    private double maxD = 40; //40 kilometers
    private double maxH = 4000; // ex. max height 3000 m
    private int height = 700;
    private int width = 700;
    private int lineWidth = 700;
    private Label infoLabel;
    private Color targetColor;
    private Label label;
    private Label currentDistanceLabel;
    private Rectangle arc;
    private Timeline targetAnimation;
    private Rectangle glissadaTarget;
    private Rectangle kursTarget;
    private int timeInterval = 1000;
    private Label altimeterAzimutLabel;
    private Label currentHeightLabel;

    @Override
    public void start(Stage primaryStage) {
        makeBasicLayout(primaryStage);
        stage.setScene(new Scene(root));
        stage.show();
    }

    public void makeBasicLayout(Stage primaryStage) {
        primaryStage.setTitle("Altimeter - height indicator");
        stage = primaryStage;
        createRoot();
    }

    public Group createRoot() {
        root = new Group();
        Line line2 = new Line(0, 0, width, width);
        line2.setStroke(Color.WHITE);
        vBox = new VBox(25);
        vBox.getChildren().addAll(line2);


        hBox = new HBox();
        hBox.getChildren().add(vBox);
        hBox.getChildren().add(addCheckBoxPanel());
        root.getChildren().add(hBox);
        addComponents();
        return root;
    }

    private void addComponents() {
        //addBars();


        //createLRV(450);

        //drawKorobochka();

        //createKursLine(0);
        //createKursLROPlus((int)(kursBarHeight / 2) );
        //createKursLROMinus(-(int) (kursBarHeight / 2));

        //createGlissadaLine(0);
        //createGlissadaLROPlus(-(int)(kursBarHeight / 4) );
        //createGlissadaLROMinus((int)(kursBarHeight / 4) );

        createDistanceLines();
        addDistanceLines();
        addAngleLines();
        createTargetAnimation();

    }

    private void createTargetAnimation() {
        if (root.getChildren().contains(arc)) {
            root.getChildren().remove(arc);
        }
        if (targetAnimation != null) {
            targetAnimation.stop();
        }
        targetAnimation = new Timeline();

        kursTarget = new Rectangle(-100,-100,5,50);
        kursTarget.setArcHeight(15);
        kursTarget.setArcWidth(35);
        kursTarget.setFill(Color.YELLOW.darker());
        root.getChildren().add(kursTarget);



        targetAnimation.stop();
        targetAnimation.getKeyFrames().add(new KeyFrame(Duration.millis(timeInterval),
                new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent actionEvent) {
                        //int pointsAmount = (int)(lineWidth - zeroKMLineOffsetPx);
                        //time++;
                        //System.out.println("t: "+ IKO.sharedTime);
                        //System.out.println(time++ + " "+ glissadaLinedoubleArray[time * 2] + "-"+ glissadaLinedoubleArray[time * 2 + 1]);
                        int index = (5*Math.round(IKO.sharedTime/1000) + 1) % Nalet.points.length;
                        //if((index<Nalet.points.length)&&(index>0)){
                        //    if(Math.abs(Nalet.points[index]-330)<1){
                        //        glissadaTarget.setX(distance2Pixel( Nalet.points[index-1]/1000));
                        //        int ind = (pointsAmount *2  - (IKO.sharedTime )% Nalet.points.length * 2)  + 1;
                        //        System.out.println("gliss id: " + ind);
                        //        if(ind>0)
                        //            glissadaTarget.setY(glissadaLinedoubleArray[ind]);
                        //
                        //    }
                        //}
                        //glissadaTarget.setX(glissadaLinedoubleArray[(pointsAmount - time) * 2] - 3);

                        //kursTarget.setX(kursLineDoubleArray[(pointsAmount - time) * 2] - 3);
                        //kursTarget.setY(kursLineDoubleArray[(pointsAmount - time) * 2 + 1] - 25);

                        //setting kurs
                        //int index = 5*Math.round(time * timeInterval/1000) + 1;


                        //if((index<Nalet.points.length)&&(index>0)){


                            //if(Math.abs(Nalet.points[index]-330)<13){
                                //if(Math.abs(Nalet.points[index]-330)>1){
                                    //330-Azimut
                                if(Math.abs(IKO.altimeterAzimut - getAzimutByTime(0))<2 )  {
                                    System.out.println(" t: "+ IKO.sharedTime + " D: " + distance2Pixel( getRadiusByTime(0))
                                            + " H: " + height2Pixel(getHeightByTime(0)) + " h: " + getHeightByTime(0));
                                    kursTarget.setX(distance2Pixel( getRadiusByTime(0)));
                                    kursTarget.setY(height2Pixel(getHeightByTime(0)));
                                    currentDistanceLabel.setText("D: " + getRadiusByTime(0));
                                    currentHeightLabel.setText("H: " + getHeightByTime(0));
                                    altimeterAzimutLabel.setText("A: " + getAzimutByTime(0));
                                }

                                //}else{
                                //    //atan2
                                //    System.out.println(" t: "+ IKO.sharedTime + " D: " + distance2Pixel( Nalet.points[index-1]/1000 )
                                //            + " kurs " + Math.atan2(kursRadarOffset, Nalet.points[index-1])/Math.PI*180);
                                //    kursTarget.setX(distance2Pixel( Nalet.points[index-1]/1000));
                                //    kursTarget.setY(kurs2Pixel(Math.atan2(kursRadarOffset, Nalet.points[index-1])/Math.PI*180));
                                //}
                            //}
                        //}
                    }
                }));
        targetAnimation.setCycleCount(Animation.INDEFINITE);
        targetAnimation.play();
    }



    private void createDistanceLines() {
        distanceLines.clear();
        for (int i = 0; i <= maxD; i++) {
            //Line line = new Line(width * Math.log10(i) / Math.log10(maxD),0,width * Math.log10(i) / Math.log10(maxD) , height);
            //line.setStrokeDashOffset(1);
            //line.setStroke(Color.WHITE);
            Path path = PathBuilder.create().elements(
                    new MoveTo(distance2Pixel(i), 0),
                    new LineTo(distance2Pixel(i), height))
                    .build();
            path.setStroke(Color.GREY);
            path.setFill(Color.GREY);
            if (i % 5 != 0) {
                path.getStrokeDashArray().setAll(1d, 15d);
            }
            if((i>=20 && i%5==0)||(i<20)){
                distanceLines.add(path);
            }
        }
    }


    private void addDistanceLines() {

        for (int i = 0; i <= (maxD==20?maxD:24); i++) {

            if (root.getChildren().contains(distanceLines.get(i))) {
                root.getChildren().remove(distanceLines.get(i));
            }
            root.getChildren().add(distanceLines.get(i));
        }
    }

    private void addAngleLines(){
        for(int i=0;i<20;i++){
            Path path = PathBuilder.create().elements(
                    new MoveTo(0, height * i / 20),
                    new LineTo(lineWidth, height * i / 20))
                    .build();
            path.setStroke(Color.GREY);
            path.setFill(Color.GREY);
            angleLines.add(path);

            //Angle labels
            Label label = new Label(" " + (20-i) * maxH / 20);
            label.setLayoutX(lineWidth - 50);
            label.setLayoutY(height * i / 20 - 10);
            root.getChildren().add(label);

            root.getChildren().add(path);
        }
    }

    private double distance2Pixel(double d) {
        return  width * d / maxD;
    }

    private double height2Pixel(double h) {
        return height - height * h  / maxH - 30;
    }

    private VBox addCheckBoxPanel() {
        VBox vbox = new VBox();
        vbox.setSpacing(10);
        final CheckBox cb4 = new CheckBox("A30");
        cb4.setSelected(true);
        cb4.setTextFill(Color.LIGHTGREY);
        final ColorPicker colorPicker = new ColorPicker();
        colorPicker.setValue(Color.YELLOW);
        infoLabel = new Label("MAX DISTANCE: 375 Km");
        infoLabel.setTextFill(Color.BLACK);
        label = new Label("Target color: ");
        label.setTextFill(Color.GREEN);
        colorPicker.setOnAction(new EventHandler() {
            @Override
            public void handle(Event arg0) {
                targetColor = colorPicker.getValue();
            }
        });
        currentDistanceLabel = new Label("D: ");
        currentHeightLabel   = new Label("H: ");
        altimeterAzimutLabel = new Label("Altimeter : ");

        vbox.getChildren().addAll(infoLabel, label, colorPicker, currentDistanceLabel, currentHeightLabel
                ,altimeterAzimutLabel
        //        , scaleComboBox, label,  radioEqualAngles, radioEqualDistance, landingAzimutComboBox
        );

        return vbox;
    }

    private double getRadiusByTime(int shadowNo) {
        //return Math.min(400, time / 360.0 * 1 + 2);
        if((IKO.sharedTime )>0){
            return Nalet.points[getIndex(0) + 0] / 1000 ;
        }else{
            return Nalet.points[0];
        }
    }

    private double getHeightByTime(int shadowNo) {
        //return Math.min(400, time / 360.0 * 1 + 2);
        if((IKO.sharedTime)>0){
            return Nalet.points[getIndex(0) + 4] ;
        }else{
            return Nalet.points[4];
        }
    }

    private double getAzimutByTime(int shadowNo) {
        //return Math.min(400, time / 360.0 * 1 + 2);
        if((IKO.sharedTime)>0){
            return Nalet.points[getIndex(0) + 1] ;
        }else{
            return Nalet.points[1];
        }
    }


    private int getIndex(int shadowNo) {
        return 5 * ((IKO.sharedTime) / 1000) % Nalet.points.length;
    }

    public static void main(String[] args) {
        launch(args);
    }
}
